thin.define(function(exports) {
    "use strict";

    function Interactive() {
        this.config = {
            host: '',
            state: {
                999: false
            },
            status: {
                999: function() {
                    return false
                }
            }
        };
    }

    // 配置
    Interactive.prototype.global = function(opts) {
        if(!opts) return;
        var self = this;
        // 全局域名
        (typeof opts.host == 'string') && (self.config.host = opts.host);
        // 全局状态
        (typeof opts.state == 'object') && (self.config.state = opts.state);
        // 全局状态码
        (typeof opts.status == 'object') && (self.config.status = opts.status);
    }

    Interactive.prototype.xhr = function(opts) {
        if(!opts) return;
        var self = this;
        var data_opt = formatParams.call(self, opts);
        requestDatabase.call(self, data_opt);
    }

    Interactive.prototype.get = function() {
        var self = this;
        var url = arguments[0] || '';
        if(url == '') return;
        var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
        var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
        var data_opt = formatParams.call(self, {
            'type': 'get',
            'url': url,
            'data': data,
            'complete': fn
        });
        requestDatabase.call(self, data_opt);
    }

    Interactive.prototype.post = function() {
        var self = this;
        var url = arguments[0] || '';
        if(url == '') return;
        var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
        var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
        var data_opt = formatParams.call(self, {
            'type': 'post',
            'url': url,
            'data': data,
            'complete': fn
        });
        requestDatabase.call(self, data_opt);
    }

    Interactive.prototype.put = function() {
        var self = this;
        var url = arguments[0] || '';
        if(url == '') return;
        var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
        var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
        var data_opt = formatParams.call(self, {
            'type': 'put',
            'url': url,
            'data': data,
            'complete': fn
        });
        requestDatabase.call(self, data_opt);
    }

    Interactive.prototype.del = function() {
        var self = this;
        var url = arguments[0] || '';
        if(url == '') return;
        var data = (arguments[1] && typeof arguments[1] == 'object') ? arguments[1] : {};
        var fn = (arguments[1] && typeof arguments[1] == 'function') ? arguments[1] : (arguments[2] || function() {});
        var data_opt = formatParams.call(self, {
            'type': 'delete',
            'url': url,
            'data': data,
            'complete': fn
        });
        requestDatabase.call(self, data_opt);
    }

    Interactive.prototype.upload = function(url, formData, complete) {
        var self = this;
        var xhr = initXHR();
        xhr.open('POST', url, true);
        xhr.onreadystatechange = function() {
            switch(xhr.readyState) {
                case 0:
                    break;
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    var result = {
                        'status': xhr.status
                    };
                    try {
                        var response = JSON.parse(xhr.responseText);
                        if(typeof response.error == 'undefined') {
                            result['data'] = response
                        } else {
                            result['error'] = response.error
                        }
                    } catch(err) {
                        result['data'] = xhr.responseText
                    }
                    detection.call(self, result, complete);
                    break;
                default:
                    break
            }
        };
        xhr.send(formData);
    };

    // -------------------------------------------------------

    // 发起请求
    function requestDatabase(opts) {
        var self = this;
        requestDatabaseXHR.call(self, opts);
    }

    // 发起请求 -- xhr
    function requestDatabaseXHR(opts) {
        var self = this;
        var xhr = initXHR();

        xhr.open(opts.type, opts.url, opts.async);
        if(opts.async === true) {
            xhr.onreadystatechange = readystatechange;
        }
        for(var i in opts.header) {
            xhr.setRequestHeader(i, opts.header[i]);
        }

        var timer = setTimeout(function() {
            timer = null;
            xhr.abort();
            xhrend({
                status: 504
            }, opts.complete);
        }, opts.timeout);

        try {
            xhr.send(opts.type === 'GET' ? null : opts.data);
        } catch(e) {
            //TODO handle the exception
        }

        if(opts.async === false) {
            readystatechange();
        }

        function readystatechange() {
            switch(xhr.readyState) {
                case 0:
                    break;
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    var result = {
                        'status': xhr.status
                    };
                    try {
                        var response = JSON.parse(xhr.responseText);
                        if(typeof response.error == 'undefined') {
                            result['data'] = response
                        } else {
                            result['error'] = response.error
                        }
                    } catch(err) {
                        result['data'] = xhr.responseText
                    }
                    if(timer) {
                        clearTimeout(timer);
                        if(opts.delayed > 0) {
                            setTimeout(function() {
                                xhrend(result, opts.complete);
                            }, opts.delayed);
                        } else {
                            xhrend(result, opts.complete);
                        }
                    }
                    break;
                default:
                    break
            }
        };

        function xhrend(result, complete) {
            // 判断是否重试
            /*if(opts.again > 0) {
                setTimeout(function() {
                    requestDatabaseXHR(opts);
                }, 1.6 * 1000);
                --opts.again;
                return;
            }*/
            detection.call(self, result, opts.complete);
        }
    }

    // 发起请求 -- xdr（未完成）
    function requestDatabaseXDR() {
        var xdr = new XDomainRequest();

        xdr.open("GET", "");
        xdr.onprogress = function() {
            //Progress
        };
        xdr.ontimeout = function() {
            //Timeout
        };
        xdr.onerror = function() {
            //Error Occurred
            console.dir(xdr);
        };
        xdr.onload = function() {
            //success(xdr.responseText);
            console.dir(xdr);
        }
        setTimeout(function() {
            xdr.send();
        }, 0);
    }

    // -------------------------------------------------------

    // 初始化xhr
    function initXHR() {
        var _xhr = null;
        try {
            _xhr = new XMLHttpRequest();
        } catch(e) {
            var IEXHRVers = ["Msxml3.XMLHTTP", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
            for(var i = 0, len = IEXHRVers.length; i < len; i += 1) {
                try {
                    _xhr = new ActiveXObject(IEXHRVers[i]);
                } catch(e) {
                    continue;
                }
            }
        }
        return _xhr;
    }

    // 过滤参数
    function formatParams(opts) {
        var self = this;
        // 请求参数
        var param = {
            type: 'get',
            url: '',
            data: {},
            header: {},
            cache: true,
            async: true,
            again: 0,
            timeout: 8000,
            delayed: 0,
            complete: new Function('')
        };

        // 请求方式
        (typeof opts.type == 'string') && (param.type = opts.type);
        // 请求地址
        (typeof opts.url == 'string') && (param.url = opts.url);
        // 请求参数
        (typeof opts.data == 'object' || typeof opts.data == 'string' || typeof opts.data == 'number') && (param.data = opts.data);
        // 请求回调
        (typeof opts.complete == 'function') && (param.complete = opts.complete);
        // 请求自定义头
        (typeof opts.header == 'object') && (param.header = opts.header);
        // 最大请求失败次数
        (typeof opts.again == 'number') && (param.again = opts.again);
        // 最长请求时间
        (typeof opts.timeout == 'number') && (param.timeout = opts.timeout);
        // 延后的时间
        (typeof opts.delayed == 'number') && (param.delayed = opts.delayed);
        // [异步|同步]
        (typeof opts.async == 'boolean') && (param.async = opts.async);

        // 过滤 type
        param.type = param.type.toUpperCase();

        // 过滤 data
        if(param.data instanceof Object) {
            var data_arrs = [];
            for(var i in param.data) {
                data_arrs.push(i + '=' + param.data[i]);
            }
            param.data = data_arrs.join('&');
        }

        // 过滤 url
        var regHost = /^(http|https|\\)/;
        if(!regHost.test(param.url)) {
            param.url = self.config.host + param.url;
        }
        if(param.type == 'GET' && param.data != '') {
            if((/\?/gi).test(param.url)) {
                param.url += '&' + param.data
            } else {
                param.url += '?' + param.data
            }
        }

        // 过滤 header
        if(param.type == 'POST' || param.type == 'PUT' || param.type == 'DELETE') {
            param.header['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
        }

        return param;
    }

    // 回调
    function detection(res, callback) {
        var self = this;
        if(typeof self.config.state[res.status] == 'boolean') {
            res['state'] = self.config.state[res.status];
        } else {
            res['state'] = false;
        }
        if(typeof self.config.status[res.status] == 'function') {
            if(self.config.status[res.status](res)) {
                callback(res)
            }
        } else {
            callback(res)
        }
    }

    // -------------------------------------------------------

    exports('ajax', new Interactive());
});